from rest_framework import serializers
from .models import Specialization, User, SpecializationType
from django.contrib.auth.models import Group
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer


class SpecializationSerializer(serializers.ModelSerializer):
    class Meta:
        model = Specialization
        fields = '__all__'
class SpecializationTypeSerializer(serializers.ModelSerializer):
    specialization = SpecializationSerializer()
    class Meta:
        model = SpecializationType
        fields = '__all__'

class UserSerializer(serializers.ModelSerializer):
    main_specialization = SpecializationSerializer()
    additional_specializations = SpecializationSerializer(many=True)

    class Meta:
        model = User
        fields = '__all__'

    def create(self, validated_data):
        main_specialization_data = validated_data.pop('main_specialization')
        additional_specializations_data = validated_data.pop('additional_specializations')
        main_specialization_name = main_specialization_data['specialization']
        groups = validated_data.pop('groups')
        validated_data.pop('user_permissions')
        try:
            Specialization.objects.get(specialization=main_specialization_name)
        except Specialization.DoesNotExist:
            raise serializers.ValidationError('Specialization does not exist')
        for specialization in additional_specializations_data:
            if main_specialization_name == specialization['specialization']:
                raise serializers.ValidationError('Main and additional specializations are the same')
            try:
                Specialization.objects.get(specialization=specialization['specialization'])
            except Specialization.DoesNotExist:
                raise serializers.ValidationError('Specialization does not exist (additional)')
        user = User.objects.create_user(**validated_data)
        user.main_specialization = Specialization.objects.get(specialization=main_specialization_name)
        user.save()
        for group in groups:
            user.groups.add(Group.objects.get(name=group))
        for specialization in additional_specializations_data:
            user.additional_specializations.add(Specialization.objects.get(specialization=specialization['specialization']))

        return user

    def update(self, instance, validated_data):
        main_specialization_data = validated_data.pop('main_specialization')
        additional_specializations_data = validated_data.pop('additional_specializations')
        main_specialization_name = main_specialization_data['specialization']
        groups = validated_data.pop('groups')
        validated_data.pop('user_permissions')
        password = validated_data.pop('password')
        try:
            Specialization.objects.get(specialization=main_specialization_name)
        except Specialization.DoesNotExist:
            raise serializers.ValidationError('Specialization does not exist')
        for specialization in additional_specializations_data:
            if main_specialization_name == specialization['specialization']:
                raise serializers.ValidationError('Main and additional specializations are the same')
            try:
                Specialization.objects.get(specialization=specialization['specialization'])
            except Specialization.DoesNotExist:
                raise serializers.ValidationError('Specialization does not exist (additional)')
        instance = super().update(instance, validated_data)
        instance.set_password(password)
        instance.main_specialization = Specialization.objects.get(specialization=main_specialization_name)
        instance.save()
        instance.groups.clear()
        for group in groups:
            instance.groups.add(Group.objects.get(name=group))
        instance.additional_specializations.clear()
        for specialization in additional_specializations_data:
            instance.additional_specializations.add(Specialization.objects.get(specialization=specialization['specialization']))

        return instance


class GroupSerializer(serializers.ModelSerializer):
    class Meta:
        model = Group
        fields = '__all__'


class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    @classmethod
    def get_token(cls, user):
        token = super().get_token(user)
        token['user_id'] = user.id
        return token

    def validate(self, attrs):
        data = super().validate(attrs)
        data['user_id'] = self.user.id
        return data
